﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Drawing;

namespace Kinect_Interface_Prototype_1.Folder_Control
{
    public class Folder : Item
    {
        private string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
        private string publicDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory);

        public Folder(string path, Icon icon)
        {
            Name = GetName(path);
            Path = path;
            Type = ItemType.Folder;
            Icon = icon;
        }

        public Folder(string name, string path, Icon icon)
        {
            Name = name;
            Path = path;
            Type = ItemType.Folder;
            Icon = icon;
        }

        public override List<Item> onClick()
        {
            return ListItemsInFolder();
        }

        public List<Item> ListItemsInFolder()
        {
            Icons icons = new Icons(Icons.SystemImageListSize.ExtraLargeIcons);

            List<Item> items = new List<Item>();
            List<string> files;
            List<string> folders;

            // Gets files and folders that are not hidden at the desktop (adds some special folders)
            if (Name.ToLower().Contains("desktop"))
            {
                files = GetDesktopFiles();
                folders = GetDesktopFolders();

                foreach (var specialFolder in SpecialFolders.SpecialFoldersForDesktopDictionary.Values)
                {
                    items.Add(specialFolder);
                }
            }
            else
            {
                // Gets files and folders that are not hidden at path
                files = GetFiles(Path);
                folders = GetFolders(Path);
            }


            foreach (var folder in folders)
            {
                Item item = new Folder(folder, icons.GetFolderIcon(folder));
                items.Add(item);
            }

            foreach (var file in files)
            {
                FileInfo fileInfo = new FileInfo(file);

                Item item;
                if (fileInfo.Extension.Equals(".lnk"))
                    item = LinkFactory.GetLink(fileInfo.Name, file, icons.GetIcon(file, true));
                else
                    item = new File(file, icons.GetIcon(file, false));

                items.Add(item);
            }

            // Disposes the icons object to save memory
            icons.Dispose();

            return items;
        }

        private List<string> GetFiles(string path)
        {
            try
            {
                return new DirectoryInfo(path).GetFiles().Where(x => (x.Attributes & FileAttributes.Hidden) == 0).Select(x => x.FullName).ToList();
            }
            catch (IOException) // returns empty list
            {
                return new List<string>();
            }
        }

        private List<string> GetFolders(string path)
        {
            try
            {
                return new DirectoryInfo(path).GetDirectories().Where(x => (x.Attributes & FileAttributes.Hidden) == 0).Select(x => x.FullName).ToList();
            }
            catch (IOException) // returns empty list
            {
                return new List<string>();
            }
        }

        private List<string> GetDesktopFiles()
        {
            List<string> files = new DirectoryInfo(desktopPath).GetFiles().Where(x => (x.Attributes & FileAttributes.Hidden) == 0).Select(x => x.FullName).ToList();
            files = files.Concat(new DirectoryInfo(publicDesktopPath).GetFiles().Where(x => (x.Attributes & FileAttributes.Hidden) == 0).Select(x => x.FullName)).ToList();

            return files;
        }

        private List<string> GetDesktopFolders()
        {
            List<string> folders = new DirectoryInfo(desktopPath).GetDirectories().Where(x => (x.Attributes & FileAttributes.Hidden) == 0).Select(x => x.FullName).ToList();
            folders = folders.Concat(new DirectoryInfo(publicDesktopPath).GetDirectories().Where(x => (x.Attributes & FileAttributes.Hidden) == 0).Select(x => x.FullName)).ToList();

            return folders;
        }
    }
}
